import json
import random
import re

from django.contrib.auth import login, authenticate
from django.http import JsonResponse
from django.views import View
from django_redis import get_redis_connection
import logging
logger = logging.getLogger('django')
from django.shortcuts import render, redirect

# Create your views here.
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework import serializers
from rest_framework.generics import UpdateAPIView

from ss1024.libs.qiniuyun.qiniu_storage import storage, QINIUYUN_URL
from ss1024.libs.yuntongxun.sms import CCP
from xj_users.models import User, Label
from xj_users.serialzier import UserSerialzier, User1Serialzier, LabelsSerialzier

# 短信验证码
class SMSCodeView(View):
    """短信验证码"""

    def get(self, request, mobile):
        """
        :param reqeust: 请求对象
        :param mobile: 手机号
        :return: JSON
        """
        # 将这句话提到前面最开始的位置:
        redis_conn = get_redis_connection('verify_code')
        # 进入函数后, 先获取存储在 redis 中的数据
        send_flag = redis_conn.get('send_flag_%s' % mobile)
        # 查看数据是否存在, 如果存在, 说明60s没过, 返回
        if send_flag:
            return JsonResponse({'code': 400,
                                 'message': '发送短信过于频繁'})
        # 7. 生成短信验证码：生成6位数验证码
        sms_code = '%06d' % random.randint(0, 999999)

        # 创建管道对象:
        pl = redis_conn.pipeline()
        # 8. 保存短信验证码
        # 短信验证码有效期，单位：300秒
        # redis_conn.setex('sms_%s' % mobile,
        #                  300,
        #                  sms_code)
        pl.setex('sms_%s' % mobile, 300, sms_code)
        pl.setex('send_flag_%s' % mobile, 60, 1)
        # 执行管道:
        pl.execute()

        # 9. 发送短信验证码
        # 短信模板
        a = CCP().send_template_sms(mobile, [sms_code, 5], 1)
        # 改为现在的写法, 注意: 这里的函数,调用的时候需要加: .delay()
        # ccp_send_sms_code.delay(mobile, sms_code)
        import logging
        logger = logging.getLogger('django')
        logger.error(a)
        print('短信...', sms_code)
        # 10. 响应结果
        if a == -1:
            return JsonResponse({'success': 'false',
                                 'sms_code': sms_code,
                                 'message': '发送短信失败(测试)'})

        else:
            return JsonResponse({'success': 'true',
                             'sms_code': sms_code,
                             'message': '发送短信成功'})


# 注册
"""注册"""
class RegisterView(APIView):

    # 注册
    def post(self, request):
        """接收参数, 保存到数据库"""
        # 1.接收参数
        mobile = request.data.get('mobile')
        sms_code_client = request.data.pop('sms_code')
        # 链接redis数据库
        redis_conn = get_redis_connection('verify_code')
        # 查找短信验证码
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        print(request.data)
        # 10.判断该值是否存在
        if not sms_code_server:
            return JsonResponse({'code': 400,
                                'message': '短信验证码过期'})
        # 11.把redis中取得值和前端发的值对比
        if sms_code_client != sms_code_server.decode():
            return JsonResponse({'code': 400,
                                'message': '验证码有误'})
        # 12.保存到数据库 (username password mobile)
        serializer = UserSerialzier(data=request.data)
        serializer.is_valid()
        serializer.save()
        return Response(serializer.data)


'''实现登录接口'''
class LoginView(View):

    def post(self, request):
        '''实现登录接口'''
        # 1.接收参数
        dict = json.loads(request.body.decode())
        username = dict.get('username')
        password = dict.get('password')
        # 2.校验(整体 + 单个)
        if not all([username, password]):
            return JsonResponse({'code': 400,
                                'errmsg': '缺少必传参数'})
        # 3.验证是否能够登录
        user = authenticate(request,
                            username=username,
                            password=password)
        # 判断是否为空,如果为空,返回
        if user is None:
            return JsonResponse({'code': 400,
                                'errmsg': '用户名或者密码错误'})

        # 6.如果记住:  设置为两周有效
        request.session.set_expiry(None)
        data = UserSerialzier(user)
        print(data.data)
        response = JsonResponse(data.data)
        # 返回响应结果
        return response

'''实现登录接口(无)'''
class LoginView2(ModelViewSet):
        serializer_class = UserSerialzier
        queryset = User.objects.all()
        # pagination_class = PageNum
        def post(self,request):
            pass



"""获取个人详情"""
class UserView(APIView):
    def get(self, request):
        a = request.user.replies.all()
        request.user.answer_question = []
        for i in a:
            request.user.answer_question.append(i)
        serializer = User1Serialzier(instance=request.user)
        return Response(serializer.data)

    def put(self,request):
        avatar = request.data.get('avatar')
        print(avatar)
        serialize = User1Serialzier(instance=request.user,
                                    data=request.data,
                                    partial=True)
        serialize.is_valid()
        serialize.save()
        return Response(serialize.data)



"""上传头像"""
class UserAvatar(APIView):
    def post(self, request):
        # 接收参数
        img = request.FILES.get("img", None)
        if img:
            # 利用七牛云提供的接口
            img_url = storage(img.read())
            avatar_url = QINIUYUN_URL+img_url
            print(avatar_url)
            # print(img_url, type(img_url))
            # request.user.avatar = img_url
            # request.user.save()
            return Response({"imgurl": avatar_url})
        else:
            return Response({"errno": "4002	",
                                 "errmsg": "无数据"})


from rest_framework.permissions import IsAdminUser, IsAuthenticated


# 修改密码
class ChangePasswordView(APIView):
    """修改密码"""

    def put(self, request):
        """实现修改密码逻辑"""
        # 接收参数
        dict = request.data

        new_password = dict.get('password')
        if not re.match(r'^[0-9A-Za-z]{6,16}$', new_password):
            return JsonResponse({'code': 400,
                                'errmsg': '密码最少6位,最长16位'})
        # 修改密码
        try:
            request.user.set_password(new_password)
            request.user.save()
        except Exception as e:
            logger.error(e)
            return JsonResponse({'code': 400,
                                      'errmsg': '修改密码失败'})
        response = JsonResponse({'code': 0,
                                      'errmsg': 'ok'})

        # # 响应密码修改结果：重定向到登录界面
        return response

# 关注标签
class  LabelsViewSet(ModelViewSet):
    serializer_class = LabelsSerialzier
    queryset = Label.objects.all()

    @action(methods=['put'], detail=True)
    def focusin(self, request, pk):
        a = Label.objects.get(id = pk)
        request.user.labels.add(a)
        return Response({
            "success": True,
            "message": "关注成功"
        })
    @action(methods=['put'],detail=True)
    def focusout(self,request, pk):
        a = Label.objects.get(id=pk)
        request.user.labels.remove(a)
        return Response({
            "success": True,
            "message": "取消成功"
        })

# 修改擅长的技术
class UpdatelabelView(APIView):
    # permission_classes = [IsAuthenticated]
    def put(self, request):
        for i in request.user.labels.all():
            request.user.labels.remove(i)
        for pk in request.data.get('labels'):
            e = Label.objects.get(id=pk)
            request.user.labels.add(e)
        return Response({
            "success": True,
            "message": "修改成功"
        })

# 前端富文本图片
class CommonView(APIView):
    def post(self, request):
        # 接收参数
        img = request.FILES.get("upload", None)
        if img:
            # 利用七牛云提供的接口
            img_url = storage(img.read())
            avatar_url = QINIUYUN_URL + img_url
            print(avatar_url)
            image_url = "http://127.0.0.1:8080/upload_success.html?image_url="+avatar_url+"&CKEditorFuncNum=1"
            return redirect(image_url)
        else:
            return Response({"errno": "4002	",
                             "errmsg": "无数据"})

"""用户关注和取消"""
class UserLikeView(APIView):
    permission_classes = [IsAuthenticated]
    def post(self, request, pk):
        user = User.objects.get(id = pk)
        request.user.idols.add(user)
        return Response({
            "success": "true",
            "message": "关注成功"
        })
    def delete(self, request, pk):
        user = User.objects.get(id=pk)
        request.user.idols.remove(user)
        return Response({
            "success": "true",
            "message": "取消关注成功"
        })
